﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using EnvDTE;
using EnvDTE80;
using SPVisualDev.Services;
using SPVisualDev.VSAddin.Services;
using SPVisualDev.VSAddin.UserControls;

namespace SPVisualDev.VSAddin.Dialogs
{
    public partial class DialogDeployTargetSelector : Form
    {
        private SpecialProject m_project;
        private SpecialSolution m_solution;
        private DTE2 m_dte;
        private string[] m_targets;
        private ConnectionDetailsStruct m_connection_details;

        public DialogDeployTargetSelector(DTE2 Dte2, SpecialSolution specialSolution, Project project)
        {
            InitializeComponent();

            m_dte = Dte2;
            m_solution = specialSolution;
            m_project = specialSolution.GetSpecialProject(project);
            m_targets = new string[] { };

            this.Load += new EventHandler(DialogDeployTargetSelector_Load);
            this.txtRemoteServerPort.GotFocus += new EventHandler(txtRemoteServerPort_GotFocus);
            this.rdoLocal.CheckedChanged += new EventHandler(rdoLocal_CheckedChanged);
        }

        void rdoLocal_CheckedChanged(object sender, EventArgs e)
        {
            try
            {
                if (this.rdoLocal.Checked)
                {
                    this.txtRemoteServerAddress.Enabled = false;
                    this.txtRemoteServerPort.Enabled = false;
                    this.btnConnect.Enabled = false;

                    PopulateWebApplicationsList();
                }
                else
                {
                    this.txtRemoteServerAddress.Enabled = true;
                    this.txtRemoteServerPort.Enabled = true;
                    this.btnConnect.Enabled = true;

                    this.lstTargets.Items.Clear();

                    //if (!string.IsNullOrEmpty(this.RemoteServerAddress))
                    //    PopulateWebApplicationsList();
                }
            }
            catch (Exception ex)
            {
                DialogError.ShowError(ex);
            }
        }

        void txtRemoteServerPort_GotFocus(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(this.txtRemoteServerPort.Text))
            {
                this.txtRemoteServerPort.Text = Common.C_WCF_MAIN_SVC_PORT.ToString();
            }
        }

        public ConnectionDetailsStruct ConnectionDetails
        {
            get { return m_connection_details; }
        }

        public string RemoteServerAddress
        {
            get { return this.txtRemoteServerAddress.Text; }
            set { this.txtRemoteServerAddress.Text = value; }
        }

        public string RemoteServerPort
        {
            get { return this.txtRemoteServerPort.Text; }
            set { this.txtRemoteServerPort.Text = value; }
        }

        public bool RemoteUse
        {
            get { return this.rdoRemote.Checked; }
        }

        public List<string> GetTargetWebApplications()
        {
            List<string> list = new List<string>();
            foreach (ListViewItem item in this.lstTargets.Items)
            {
                if (item.Checked)
                {
                    list.Add(item.SubItems[1].Text);
                }
            }

            return list;
        }


        public string InfoMessage
        {
            get { return this.lblInfo.Text; }
            set { this.lblInfo.Text = value; }
        }

        void DialogDeployTargetSelector_Load(object sender, EventArgs e)
        {
            this.txtRemoteServerPort.Text = Common.C_WCF_MAIN_SVC_PORT.ToString();

            LoadConfig();

            if (Connect.S_Client_Install && this.rdoRemote.Checked == false)
            {
                this.rdoRemote.Checked = true;
                this.rdoLocal.Checked = false;
                this.rdoLocal.Enabled = false;

            }
            else
            {
                //this.rdoLocal.Checked = true;
            }

        }


        private void LoadConfig()
        {
            string remoteServer = "";
            string port = "";
            string userName = "";
            string passWord = "";
            string targets = string.Empty;

            m_connection_details = new ConnectionDetailsStruct();

            if (m_project == null)
            {
                remoteServer = m_solution.GetUserSettingsValue("DeployTargetServerAddress");
                port = m_solution.GetUserSettingsValue("DeployTargetServerPort");
                userName = m_solution.GetUserSettingsValue("DeployTargetServerUserName");
                passWord = m_solution.GetUserSettingsValue("DeployTargetServerPassword");
                targets = m_solution.GetUserSettingsValue("DeployTargetWebApplications");
            }
            else
            {
                remoteServer = m_project.GetUserSettingsValue("DeployTargetServerAddress");
                port = m_project.GetUserSettingsValue("DeployTargetServerPort");
                userName = m_project.GetUserSettingsValue("DeployTargetServerUserName");
                passWord = m_project.GetUserSettingsValue("DeployTargetServerPassword");
                targets = m_project.GetUserSettingsValue("DeployTargetWebApplications");
            }

            this.RemoteServerAddress = remoteServer;
            this.RemoteServerPort = (string.IsNullOrEmpty(port)) ? Common.C_WCF_MAIN_SVC_PORT.ToString() : port;

            if (!string.IsNullOrEmpty(userName))
                m_connection_details.UserName = Common.DecryptUsingKeyContainer(userName);

            if (!string.IsNullOrEmpty(passWord))
                m_connection_details.Password = Common.DecryptUsingKeyContainer(passWord);


            if (string.IsNullOrEmpty(this.RemoteServerAddress))
            {
                this.RemoteServerAddress = "";
                this.rdoLocal.Checked = true;
            }
            else
            {
                this.rdoRemote.Checked = true;
            }

            if (targets == null)
                targets = "";

            try
            {
                m_targets = targets.Split(';');

                PopulateWebApplicationsList();
            }
            catch (Exception ex)
            {
                DialogError.ShowError(ex);
            }
        }

        private void SaveConfig()
        {
            string targets = string.Empty;

            foreach (ListViewItem item in this.lstTargets.Items)
            {
                if (item.Checked)
                {
                    if (targets != "")
                        targets += ";";

                    targets += item.SubItems[1].Text;
                }
            }


            if (m_project == null)
            {
                m_solution.SetUserSettingsValue("DeployTargetServerAddress", (this.rdoLocal.Checked) ? "" : this.RemoteServerAddress, false);
                m_solution.SetUserSettingsValue("DeployTargetServerPort", this.RemoteServerPort, false);
                m_solution.SetUserSettingsValue("DeployTargetWebApplications", targets, false);

                if (this.RemoteUse && !string.IsNullOrEmpty(m_connection_details.UserName))
                {
                    m_solution.SetUserSettingsValue("DeployTargetServerUserName", Common.EncryptUsingKeyContainer(m_connection_details.UserName), false);
                    m_solution.SetUserSettingsValue("DeployTargetServerPassword", Common.EncryptUsingKeyContainer(m_connection_details.Password), false);
                }
                else
                {
                    m_solution.SetUserSettingsValue("DeployTargetServerUserName", "", false);
                    m_solution.SetUserSettingsValue("DeployTargetServerPassword", "", true);
                }
            }
            else
            {
                m_project.SetUserSettingsValue("DeployTargetServerAddress", (this.rdoLocal.Checked) ? "" : this.RemoteServerAddress, false);
                m_project.SetUserSettingsValue("DeployTargetServerPort", this.RemoteServerPort, false);
                m_project.SetUserSettingsValue("DeployTargetWebApplications", targets, false);

                if (this.RemoteUse && !string.IsNullOrEmpty(m_connection_details.UserName))
                {
                    m_project.SetUserSettingsValue("DeployTargetServerUserName", Common.EncryptUsingKeyContainer(m_connection_details.UserName), false);
                    m_project.SetUserSettingsValue("DeployTargetServerPassword", Common.EncryptUsingKeyContainer(m_connection_details.Password), false);
                }
                else
                {
                    m_project.SetUserSettingsValue("DeployTargetServerUserName", "", false);
                    m_project.SetUserSettingsValue("DeployTargetServerPassword", "", true);
                }
            }
        }

        private void PopulateWebApplicationsList()
        {
            List<IExplorerObjectContainer> listOfwebApps = new List<IExplorerObjectContainer>();
            this.lstTargets.Items.Clear();

            if (this.rdoLocal.Checked)
            {
                m_connection_details.Address = "localhost";
                m_connection_details.Port = Common.C_WCF_MAIN_SVC_PORT;

                if (!Connect.S_Client_Install)
                {
                    m_connection_details.UseInProc = !SharePointLibrary.CheckIf32bitOn64();
                }
                else
                {
                    return;
                }
            }
            else
            {
                m_connection_details.Address = this.RemoteServerAddress;
                m_connection_details.Port = int.Parse(this.RemoteServerPort);
                m_connection_details.UseInProc = false;
            }

            using (MainServiceWrapper svc = new MainServiceWrapper(m_connection_details, true))
            {
                //Update local connection details if login was done.
                m_connection_details.UserName = svc.ConnectionDetails.UserName;
                m_connection_details.Password = svc.ConnectionDetails.Password;

                listOfwebApps = svc.ServiceProxy.GetChildren(new ExFarm(), "Web applications");
            }

            foreach (ExWebApplication webapp in listOfwebApps)
            {
                ListViewItem item = new ListViewItem(new string[] { webapp.Title, webapp.Url });
                item.Checked = (Array.IndexOf(m_targets, webapp.Url) != -1);

                this.lstTargets.Items.Add(item);
            }
        }

        private void btnConnect_Click(object sender, EventArgs e)
        {
            try
            {
                if (string.IsNullOrEmpty(this.RemoteServerAddress))
                {
                    throw new Exception("No address specified.");
                }

                if (string.IsNullOrEmpty(this.txtRemoteServerPort.Text))
                {
                    this.RemoteServerPort = Common.C_WCF_MAIN_SVC_PORT.ToString();
                }

                m_connection_details.Address = this.RemoteServerAddress;
                m_connection_details.Port = int.Parse(this.RemoteServerPort);

                PopulateWebApplicationsList();

            }
            catch (Exception ex)
            {
                DialogError.ShowError(ex);
            }
        }

        private void btnOK_Click(object sender, EventArgs e)
        {
            try
            {
                //Test connection settings
                PopulateWebApplicationsList();


                SaveConfig();

                this.DialogResult = DialogResult.OK;
                this.Hide();
            }
            catch(Exception ex)
            {
                DialogError.ShowError(ex);
            }
        }

    }
}
